﻿using System;
using System.Collections.Generic;
using System.Text;
using Vortex.Wrapper.Direct3D;
using System.Drawing;
using Vortex.IO;
using Vortex.Wrapper;
using Vortex.Debugging;

namespace Vortex.Drawing {
	/// <summary>
	/// Texture class. Texture is 2D image which contains pixel data.
	/// </summary>
	public class Texture : BaseTexture {

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="Texture"/> class from bitmap.
		/// </summary>
		/// <param name="bitmap">The source bitmap.</param>
		public Texture(Bitmap bitmap) {
			if (null == bitmap) throw new ArgumentNullException("bitmap");

			PixelFormat textureFormat = ImageHelper.FindMatchingTextureFormat(bitmap.PixelFormat);
			if (textureFormat == PixelFormat.Unknown) {
				throw new ArgumentException(string.Format("Specified bitmap with format '{0}' can't be used for intializing texture", bitmap.PixelFormat));
			}

			InitializeBySizeAndFormat(bitmap.Width, bitmap.Height, textureFormat);
			Surface.SetBitmapData(bitmap);
		}

		/// <summary>
		/// Creates <see cref="Texture"/> from specified file with alpha channel support.
		/// </summary>
		/// <param name="fileName">Name of the file.</param>
		public Texture(string fileName)
			: this(fileName, PixelFormat.A8R8G8B8) {
		}


		/// <summary>
		/// Creates <see cref="Texture"/> from specified file.
		/// </summary>
		/// <param name="fileName">Name of the file.</param>
		/// <param name="format">The forced format of texture.</param>
		public Texture(string fileName, PixelFormat format) {
			byte[] fileData = new ResourceFileInfo(fileName).GetContent();

			Direct3DTexture9 texture;
			HResult result = D3DX.CreateTextureFromFileInMemoryEx(Device.ApiRef, fileData, D3DX.Default_NonPow2, D3DX.Default_NonPow2, 1, D3DUsage.None, (D3DFormat)format, D3DPool.Managed, D3DXImageFilter.Default, D3DXImageFilter.Default, 0, out texture);
			Watcher.AssertCritical(result, "Create texture from file '{0}'", fileName);

			Initialize(texture);
		}

		/// <summary>
		/// Creates <see cref="Texture"/> from parameters.
		/// </summary>
		/// <param name="width">The width of texture.</param>
		/// <param name="height">The height of texture.</param>
		/// <param name="format">The format of texture.</param>
		public Texture(int width, int height, PixelFormat format) {
			InitializeBySizeAndFormat(width, height, format);
		}

		#endregion

		/// <summary>
		/// Initializes the texture by size and format.
		/// </summary>
		/// <param name="width">The width of texture.</param>
		/// <param name="height">The height of texture.</param>
		/// <param name="format">The format of texture.</param>
		private void InitializeBySizeAndFormat(int width, int height, PixelFormat format) {
			ValidateSize(width, height);

			Direct3DTexture9 texture;
			HResult result = Device.ApiRef.CreateTexture((uint)width, (uint)height, 1, D3DUsage.None, (D3DFormat)format, D3DPool.Managed, out texture);
			Watcher.AssertCritical(result, "Create texture from parameters: {0}x{1}:{2}'", width, height, format);

			Initialize(texture);
		}

		/// <summary>
		/// Gets the texture primary top surface.
		/// </summary>
		/// <value>The surface object.</value>
		public Surface Surface {
			get { return _surface; }
		}

		//public void LoadImage(string 
	}
}
